home *** CD-ROM | disk | FTP | other *** search
/ The Programmer Disk / The Programmer Disk (Microforum).iso / xpro / c4 / pro20 / pbmtomac.c < prev    next >
C/C++ Source or Header  |  1990-05-31  |  6KB  |  281 lines

  1. /* pbmtomacp.c - read a portable bitmap and produce a MacPaint bitmap file
  2. **
  3. ** Copyright (C) 1988 by Douwe vand der Schaaf.
  4. **
  5. ** Permission to use, copy, modify, and distribute this software and its
  6. ** documentation for any purpose and without fee is hereby granted, provided
  7. ** that the above copyright notice appear in all copies and that both that
  8. ** copyright notice and this permission notice appear in supporting
  9. ** documentation.  This software is provided "as is" without express or
  10. ** implied warranty.
  11. */
  12.  
  13. #include <stdio.h>
  14. #include "pbm.h"
  15. #include "macp.h"
  16.  
  17. #define TRUE        1
  18. #define FALSE        0
  19. #define EQUAL        1
  20. #define UNEQUAL        0
  21.  
  22. FILE *fdout;
  23. char *usage = "[-l left] [-r right] [-b bottom] [-t top] [pbmfile]";
  24.  
  25. main(argc, argv)
  26. int argc;
  27. char *argv[];
  28. { FILE *ifd;
  29.   register bit **bits, **bitsr;
  30.   int argn, rows, cols;
  31.   int left,bottom,right,top;
  32.   int lflg, rflg, tflg, bflg;
  33.   char name[100];
  34.  
  35.   pm_progname = argv[0];
  36.  
  37.   argn = 1;
  38.   fdout = stdout;
  39.   lflg = rflg = tflg = bflg = 0;
  40.  
  41.   while ( argn < argc && argv[argn][0] == '-' )
  42.   { switch ( argv[argn][1] )
  43.     { case 'l':
  44.       lflg++;
  45.       argn++;
  46.       left = atoi( argv[argn] );
  47.       break;
  48.  
  49.       case 'r':
  50.       rflg++;
  51.       argn++;
  52.       right = atoi( argv[argn] );
  53.       break;
  54.  
  55.       case 't':
  56.       tflg++;
  57.       argn++;
  58.       top = atoi( argv[argn] );
  59.       break;
  60.  
  61.       case 'b':
  62.       bflg++;
  63.       argn++;
  64.       bottom = atoi( argv[argn] );
  65.       break;
  66.  
  67.       case '?':
  68.       default:
  69.       pm_usage( usage );
  70.     }
  71.     argn++;
  72.   }
  73.  
  74.   if ( argn == argc )
  75.   { ifd = stdin;
  76.     strcpy( name, "noname" );
  77.   }
  78.   else
  79.   { ifd = pm_openr( argv[argn] );
  80.     strcpy( name, argv[argn] );
  81.   }
  82.  
  83.   bitsr = pbm_readpbm( ifd, &cols, &rows );
  84.  
  85.   pm_close( ifd );
  86.  
  87.   bits = pbm_allocarray( MAX_COLS, MAX_LINES );
  88.  
  89.   if( !lflg )
  90.     left = 0;
  91.  
  92.   if( rflg )
  93.   { if( right - left >= MAX_COLS )
  94.       right = left + MAX_COLS - 1;
  95.   }
  96.   else
  97.     right = ( left + MAX_COLS > cols ) ? ( cols - 1 ) : ( left + MAX_COLS - 1 );
  98.  
  99.   if( !tflg )
  100.     top = 0;
  101.  
  102.   if( bflg )
  103.   { if( bottom - top >= MAX_LINES )
  104.       bottom = top + MAX_LINES - 1;
  105.   }
  106.   else
  107.     bottom = ( top + MAX_LINES > rows ) ?
  108.            ( rows - 1 ) : ( top + MAX_LINES - 1 );
  109.   
  110.     if( right <= left || left < 0 || right - left + 1 > MAX_COLS )
  111.       pm_error("error in right (= %d) and/or left (=%d)",right,left, 0,0,0 );
  112.     if( bottom <= top || top < 0 || bottom - top + 1 > MAX_LINES )
  113.       pm_error("error in bottom (= %d) and/or top (=%d)",bottom,top, 0,0,0 );
  114.  
  115.   fillbits( bits, bitsr, top, left, bottom, right );
  116.  
  117.   writemacp( bits );
  118.  
  119. } /* main */
  120.  
  121. /* - - - - - - - - - - - - - - - - - - - - - - - - - - */
  122.  
  123. /* centreer het over te zenden plaatje in het MacPaint document
  124.  *
  125.  * Het plaatje wordt vanaf al of niet opgegeven (left, bottom)
  126.  * in een pbm bitmap van de juist macpaint afmetingen gezet,
  127.  * en eventueel afgekapt.
  128.  */
  129. fillbits( bits, bitsr, top, left, bottom, right )
  130. bit **bits, **bitsr;
  131. int top, left, bottom, right;
  132. { register bit *bi, *bir;
  133.   register int i, j;
  134.   register int bottomr, leftr, topr, rightr;
  135.   int width, height;
  136.  
  137.   width = right - left + 1;
  138.   leftr = (MAX_COLS - width) / 2;
  139.   rightr = leftr + width - 1;
  140.  
  141.   height = bottom - top + 1;
  142.   topr = ( MAX_LINES - height ) / 2;
  143.   bottomr = topr + height - 1;
  144.  
  145.   for( i = 0; i < topr; i++ )
  146.   { bi = bits[i];
  147.     for( j = 0; j < MAX_COLS; j++ )
  148.       *bi++ = 0;
  149.   }
  150.  
  151.   for( i = topr; i <= bottomr; i++ )
  152.   { bi = bits[i];
  153.     { for( j = 0; j < leftr; j++ )
  154.     *bi++ = 0;
  155.       bir = bitsr[ i - topr + top ];
  156.       for( j = leftr; j <= rightr; j++ )
  157.     *bi++ = bir[j - leftr + left];
  158.       for( j = rightr + 1; j < MAX_COLS; j++ )
  159.     *bi++ = 0;
  160.   } }
  161.  
  162.   for( i = bottomr + 1; i < MAX_LINES; i++ )
  163.   { bi = bits[i];
  164.     for( j = 0; j < MAX_COLS; j++ )
  165.       *bi++ = 0;
  166.   }
  167. } /* fillbits */
  168.       
  169. /* - - - - - - - - - - - - - - - - - - - - - - - - - - */
  170.  
  171. writemacp( bits )
  172. bit **bits;
  173. { register int i;
  174.   bit pb[MAX_COLS * 2];
  175.   int npb;
  176.  
  177.   header();
  178.   for( i=0; i < MAX_LINES; i++ )
  179.   { npb = packit( pb, bits[i] );
  180.     sendbytes( pb, npb );
  181.   }
  182. } /* writemacp */
  183.  
  184. /* - - - - - - - - - - - - - - - - - - - - - - - - - - */
  185.  
  186. /* pack regel van MacPaint doc in Apple's format
  187.  * return value = # of bytes in pb 
  188.  */
  189. int
  190. packit( pb, bits )
  191. bit *pb, *bits;
  192. { register int charcount, npb, newcount, flg;
  193.   bit temp[72];
  194.   bit *count, *srcb, *destb, save;
  195.  
  196.   srcb = bits; destb = temp;
  197.   filltemp( destb, srcb );
  198.   srcb = temp;
  199.   destb = pb;
  200.   npb = 0;
  201.   charcount = BYTES_WIDE;
  202.   flg = EQUAL;
  203.   while( charcount )
  204.   { save = *srcb++;
  205.     charcount--;
  206.     newcount = 1;
  207.     while( (*srcb == save) && charcount )
  208.     { srcb++;
  209.       newcount++;
  210.       charcount--;
  211.     }
  212.     if( newcount > 2 )
  213.     { count = destb++;
  214.       *count = 257 - newcount;
  215.       *destb++ = save;
  216.       npb += 2;
  217.       flg = EQUAL;
  218.     }
  219.     else
  220.     { if( flg == EQUAL )
  221.       { count = destb++;
  222.     *count = newcount - 1;
  223.     npb++;
  224.       }
  225.       else
  226.     *count += newcount;
  227.       while( newcount-- )
  228.       { *destb++ = save;
  229.         npb++;
  230.       }
  231.       flg = UNEQUAL;
  232.   } }
  233.   return npb;
  234. } /* packit */
  235.  
  236. /* - - - - - - - - - - - - - - - - - - - - - - - - - - */
  237.  
  238. filltemp( dest, src )
  239. bit *src, *dest;
  240. { register unsigned char ch, zero, acht;
  241.   register int i, j;
  242.  
  243.   zero = '\0';
  244.   acht = 8;
  245.   i = BYTES_WIDE;
  246.   while( i-- )
  247.   { ch = zero; 
  248.     j = acht;
  249.     while( j-- )
  250.     { ch <<= 1;
  251.       if( *src++ )
  252.     ch++;
  253.     }
  254.     *dest++ = ch;
  255.   }
  256. } /* filltemp */
  257.  
  258. /* - - - - - - - - - - - - - - - - - - - - - - - - - - */
  259.  
  260. sendbytes( pb, npb )
  261. bit *pb;
  262. register int npb;
  263. { register bit *b;
  264.  
  265.   b = pb;
  266.   while( npb-- )
  267.     putc( *b++, fdout );
  268. } /* sendbytes */
  269.  
  270. /* - - - - - - - - - - - - - - - - - - - - - - - - - - */
  271.  
  272. header()
  273. { register int i;
  274.   register char ch;
  275.  
  276.   /* header contains nothing ... */
  277.   ch = '\0';
  278.   for(i = 0; i < HEADER_LENGTH; i++ )
  279.     putc( ch, fdout );
  280. } /* header */
  281.